I am sharing here my experience of building an announcement system based on Formidable Pro (currently at version 2.14).
The notification system is created for membership websites where admins can send personalized notifications to single or multiple users.
Components:
1. The form is a simple form with a textarea and 2 checkboxes. Leave the checkboxes empty but check the “Use separate values” checkbox in their properties
2. The admin view and page will allow admins to create, edit and delete notifications
3. The public view will allow recipients to read and “mark as read” the notifications
4. The custom code that is explained below:
Populate user fields (Recipients and Read by in my case or field_id 124 and 212)
//for fields with separate values update field definition so it can render correctly in views function update_bulk_options_db($list,$ids) { global $wpdb; $id = implode(",",$ids); $options = array(); $j=0; foreach ($list as $key=>$val) { $j=$j+1; $options[$j]=array('value'=>(string)$key,'label'=>$val); } $save= serialize($options); $wpdb->query( "UPDATE wp_frm_fields SET options = '$save' WHERE id in ($id) " ); return; } //populate user related fields with users. here I use s2member plugin for role management add_filter('frm_setup_new_fields_vars', 'paperplus_populate_users', 20, 2); add_filter('frm_setup_edit_fields_vars', 'paperplus_populate_users', 20, 2); //use this function on edit too function paperplus_populate_users($values, $field){ if($field->id == 124||$field->id == 212){ $users1q = new WP_User_Query(array( 'role' => 'subscriber' )); $operators = $users1q->results; $users2q = new WP_User_Query(array( 'role' => 's2member_level1' )); $managers = $users2q->results; $users3q = new WP_User_Query(array( 'role' => 'administrator' )); $admins = $users3q->get_results(); $users = array_unique(array_merge($operators, $managers, $admins)); unset($values['options']); $values['options'] = array(); foreach($users as $u){ $values['options'][$u->ID] = $u->display_name; } update_bulk_options_db ($values['options'], array(124,212)); $values['use_key'] = true; } return $values; }
After adding this snippet to your functions.php file in your active theme you will get prepopulated checkboxes with current users registered for the subscriber, s2member_level1 and administrator roles. Of course you will use any number of roles you like or all existing users, just format properly the WP_User_Query
Filter the notifications view so that only notifications sent to current user will be displayed
Of course, a notification can be sent to several users at once. We need to filter entries that have current user id in the recipients list
//filter the notifications view if the user is in the list. add_filter('frm_where_filter', 'filter_anunturi', 10, 2); function filter_anunturi($where, $args){ if ( $args['display']->ID == 82){ //change 82 with your view id $user_id = get_current_user_id(); if ($user_id > 0) { $where = "(FIND_IN_SET('" . $user_id . "', fn_parse_ser_array(meta_value))>0 and fi.id='124')"; } } return $where; }
You notice the mysql function call fn_parse_ser_array that is a custom made function. You need phpmyadmin access and rights to create functions on your database. This function is the mysql version of the PHP function unserialize.
You may try this mysql command:
BEGIN declare cnt int; declare i int; declare retstr varchar(2000); declare mystr varchar(2000); -- declare str varchar(2000); if instr(str,"{")>0 then set str = right(str, length(str)-instr(str,"{")); set str = replace(str,"}",""); -- set retstr = str; set cnt = subStringCount2(str,";"); -- select @str; set i = 1; set retstr = ''; WHILE i< =cnt DO if mod(i,2)=0 then set mystr = SPLIT_STR2(str,";",i); set mystr = replace(mystr, '"',''); set mystr = SUBSTRING_INDEX(mystr, ':',-1); if length(retstr)>0 then set retstr = concat(retstr, ',', mystr); else set retstr = mystr; end if; end if; set i = i +1; END while; else set retstr = str; end if; return retstr; END
Also, we would want to hide the notifications that recipients have already marked as read. First idea is to use a negate condition on field 212 but… it does not work. In fact
$where = "(FIND_IN_SET('" . $user_id . "', fn_parse_ser_array(meta_value))=0 and fi.id='212')";
would work on its own but this will never work:
$where = "(FIND_IN_SET('" . $user_id . "', fn_parse_ser_array(meta_value))>0 and fi.id='124') AND (FIND_IN_SET('" . $user_id . "', fn_parse_ser_array(meta_value))=0 and fi.id='212')";
Therefore my solution was to hide the read notifications in the table itself by using DataTables jQuery plugin
Mark as read system for notifications
This system will both hide notifications for users that read them and will show admins who actually read their notifications
First add this snippet to functions.php file then add the [mark_as_read entry_id='[id]’] shortcode into the last column of the notifications table inside the view
//mark notifications as read by users add_shortcode('mark_as_read','function_mark_as_read'); function function_mark_as_read($atts) { $entry = $atts["entry_id"]; $val = FrmProEntriesController::get_field_value_shortcode(array('field_id' => 212, 'entry' => $entry, 'show' => 1)); if ($val) $val = explode(",",str_replace(" ","",$val)); else $val = array(); if (in_array(get_current_user_id(),$val)) return "Read"; else array_push($val,get_current_user_id()); //$val = array_unique($val); $new_val = "[" . implode(",",$val) . "]"; //return FrmProEntriesController::entry_update_field(array('id' => $entry, 'field_id' => 212, 'label' => 'Mark as read', 'class' => '', 'value' => $new_val, 'message' => 'Succes!')); return 'Mark as read'; }
Note that the attempt to use Formidable API failed in this case because instead of this new value [1,2,3] it will always insert this new value ‘[1,2,3]’ messing the checkbox values in the database… (maybe this is a Formidable but at this moment). So I had to copy the behaviour and hardcode it in the last line.
In the datatables initialization we need to add the searchCols filtering as in the next example:
jQuery(document).ready(function() {jQuery('.ppl_table').DataTable({ "language": { "url": "//cdn.datatables.net/plug-ins/1.10.9/i18n/Romanian.json" }, "searchCols": [ null, null, { "search": "Mark" } ] } );} );
Download
Below you can copy this exported definition of the form and views for your reference and save it as xml file, then import it into Formidable plugin. Please check the fields id that may change, also in the previous section I translated Mark and Read, in the original definitions they are in Romanian language
< ?xml version="1.0" encoding="UTF-8" ?>Paper Plus Sat, 03 Oct 2015 11:06:59 +0000